import static org.junit.Assert.*;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;

import models.Component;
import models.ComponentUser;
import models.Event;
import models.EventType;
import models.Project;
import models.Task;
import models.TaskStatus;
import models.TaskType;
import models.TaskUser;
import models.TaskUserUser;
import models.User;
import models.UserStory;

import org.junit.Before;
import org.junit.Test;

import controllers.Events;
import controllers.Tasks;
import controllers.Users;

import play.test.Fixtures;
import play.test.UnitTest;

public class C3Story7and8and12 extends UnitTest {
	@Before
	public void setUp() {
		Fixtures.deleteAll();
	}

	@Test
	public void testGetTaskAssignee() {
		User rana = new User("Rana", "123", "Morsy", "r257", "password1",
				"r257@hotmail.com", "1234", "15", "1254", "1325", "1").save();
		Task task2 = new Task().save();
		new TaskUserUser(rana, task2).save();
		User assignee = task2.getTaskAssignee();
		assertEquals(assignee, rana);

	}

	// S7
	@Test
	public void testGetUserComponent() {
		Project GUCMafia = new Project(
				"GUCMafia",
				20,
				true,
				"This is a joint venture between the GUC and the mafia aiming to kill the life out of GUCians")
				.save();
		Component comp1 = new Component("c3", "User Stories", GUCMafia).save();
		User salem = new User("Salem", "sayed", "Abdel Gawad", "salemsayed",
				"123", "salemsayed@gmail.com", "0101420501", "84 bla", "Cairo",
				"Egypt", "").save();
		new ComponentUser(true, salem, comp1).save();
		Component c = Users.getUserComponent((Long) salem.getEntityId(),
				(Long) GUCMafia.getEntityId());
		assertEquals(c, comp1);

	}

	@Test
	public void testCreateTask() {
		User nemo = new User("nemo", "123", "timmy", "nemo.timmy", "password2",
				"r257@hotmail.com", "1234", "15", "1254", "1325", "1").save();
		long userId = (Long) nemo.getEntityId();
		Project p = new Project("", 1, true, "");
		p.save();
		EventType sprint = new EventType("Sprint").save();
		Event eventSprint = new Event();
		eventSprint.type = sprint;
		eventSprint.project = p;
		eventSprint.save();
		TaskStatus status = new TaskStatus("t1", true);
		TaskType type = new TaskType("t2", true);
		status.save();
		type.save();
		UserStory story1 = new UserStory().save();
		Task.createTask(" ", "TestTask", "Low", (Long) type.getEntityId(),
				(Long) status.getEntityId(), null, null,
				(Long) p.getEntityId(), (Long) story1.getEntityId(),
				(Long) eventSprint.getEntityId(), userId);
		Task t = Task.find("byDetails", "TestTask").first();
		assertNotNull(t);
		assertEquals(story1, t.userStory);
		// assertEquals(eventSprint,t.events.get(0));
		// will return false as the db isnt reloaded yet so i can not access
		// t.events.get(0)
	}

	@Test
	public void testEditTask() {
		User nemo = new User("nemo", "123", "timmy", "nemo.timmy", "password2",
				"r257@hotmail.com", "1234", "15", "1254", "1325", "1").save();
		Project project = new Project("", 1, true, "");
		project.save();
		Component comp1 = new Component("C1", "User Stories", project).save();
		EventType defaultType = new EventType("Default").save();
		Event event = new Event();
		event.type = defaultType;
		event.project = project;
		event.save();
		EventType sprint = new EventType("Sprint").save();
		Event eventSprint = new Event();
		eventSprint.type = sprint;
		eventSprint.project = project;
		eventSprint.save();
		TaskStatus status = new TaskStatus("t1", true);
		TaskType type = new TaskType("t2", true);
		status.save();
		type.save();
		UserStory story1 = new UserStory();
		story1.story = "story 1";
		story1.component = comp1;
		story1.save();
		long userId = (Long) nemo.getEntityId();
		Task.createTask(" ", "TestTask", "Low", (Long) type.getEntityId(),
				(Long) status.getEntityId(), null, null, (Long) project
						.getEntityId(), (Long) story1.getEntityId(),
				(Long) eventSprint.getEntityId(), userId);

		Task task = Task.find("byDetails", "TestTask").first();
		task.creator = nemo;
		task.save();

		UserStory story2 = new UserStory();
		story2.story = "story 2";
		story2.component = comp1;
		story2.save();
		story2.creator = nemo;
		Task.editTask(" ", "TestTask", "Low", (Long) type.getEntityId(),
				(Long) status.getEntityId(), null, (Long) task.getEntityId(),
				(Long) project.getEntityId(), (Long) story2.getEntityId(),
				null, 0L, userId, "");
		assertEquals(story2, task.userStory);

	}

	@Test
	public void testGetTaskSprintCurrent() {
		Calendar cal1 = new GregorianCalendar();
		cal1.set(2010, Calendar.APRIL, 01);
		Calendar cal2 = new GregorianCalendar();
		cal2.set(2010, Calendar.APRIL, 28);
		Calendar cal3 = new GregorianCalendar();
		cal3.set(2010, Calendar.APRIL, 01);
		Calendar cal4 = new GregorianCalendar();
		cal4.set(2010, Calendar.MAY, 20);

		Project project = new Project("", 1, true, "");
		project.save();
		Task task1 = new Task().save();
		Event sprint1 = Events.getTaskSprintCurrent(task1);
		assertNull(sprint1);

		Task task2 = new Task().save();
		EventType et2 = new EventType("Sprint").save();
		Event sprint3 = new Event("CoolSoft sprint", "sprint 1", "C7.301",
				cal1, cal2);
		sprint3.project = project;
		sprint3.type = et2;
		sprint3.status = true;
		sprint3.tasks.add(task2);
		sprint3.save();

		Event sprint2 = new Event("CoolSoft sprint", "sprint 1", "C7.301",
				cal3, cal4);
		sprint2.project = project;
		sprint2.type = et2;
		sprint2.status = true;
		sprint2.tasks.add(task2);
		sprint2.save();
		task2.events.add(sprint2);

		Event sprint = Events.getTaskSprintCurrent(task2);
		assertEquals(sprint2, sprint);
	}

	@Test
	public void testGetTaskEventCurrent() {
		Task task = new Task().save();
		Calendar cal1 = new GregorianCalendar();
		cal1.set(2010, Calendar.APRIL, 01);
		Calendar cal2 = new GregorianCalendar();
		cal2.set(2010, Calendar.APRIL, 28);
		Calendar cal3 = new GregorianCalendar();
		cal3.set(2010, Calendar.APRIL, 01);
		Calendar cal4 = new GregorianCalendar();
		cal4.set(2010, Calendar.MAY, 20);

		Project project = new Project("", 1, true, "").save();

		EventType et2 = new EventType("Sprint").save();
		EventType et3 = new EventType("Customized Meeting").save();

		Event sprint2 = new Event("CoolSoft sprint", "sprint 1", "C7.301",
				cal3, cal4);
		sprint2.project = project;
		sprint2.type = et2;
		sprint2.status = true;
		sprint2.tasks.add(task);
		sprint2.save();
		task.events.add(sprint2);

		Event event = new Event("CoolSoft sprint", "sprint 1", "C7.301", cal3,
				cal4);
		event.project = project;
		event.type = et3;
		event.status = true;
		event.tasks.add(task);
		event.save();
		task.events.add(event);

		List<Event> events = Events.getTaskEventsNotPast(task);
		List<Event> expected = new LinkedList<Event>();
		expected.add(event);
		assertEquals(expected, events);

	}

	@Test
	public void testCheckListEqual() {
		LinkedList l1 = null;
		LinkedList l2 = null;
		assertTrue(Tasks.checkListEqual(l1, l2));

		l1 = new LinkedList();
		l2 = new LinkedList();
		assertTrue(Tasks.checkListEqual(l1, l2));

		String s1 = "s1";
		String s2 = "s2";
		l1.add(s1);
		l1.add(s2);
		l2.add(s2);
		l2.add(s1);
		assertTrue(Tasks.checkListEqual(l1, l2));
	}

	@Test
	public void testStoriesEqual() {
		UserStory story1 = null;
		UserStory story2 = null;

		assertTrue(Tasks.checkStoriesEqual(story1, story2));

		// story1 = new UserStory();
		// assertFalse(Tasks.checkStoriesEqual(story1, story2));

		story2 = new UserStory();
		story1 = new UserStory();
		assertFalse(Tasks.checkStoriesEqual(story1, story2));
	}

	@Test
	public void testRequestReviewTask() {
		User nemo = new User("nemo", "123", "timmy", "nemo.timmy", "password2",
				"r257@hotmail.com", "1234", "15", "1254", "1325", "1").save();
		Task task = new Task().save();
		Project project = new Project("", 1, true, "").save();
		EventType et4 = new EventType("Default").save();
		Event event = new Event();
		event.type = et4;
		event.tasks.add(task);
		event.project = project;
		event.save();
		task.events.add(event);
		new TaskUserUser(nemo, task).save();
		task.requestReviewTask((Long) nemo
				.getEntityId());
		User reviewer = task.getTaskReviewer(false);
		assertEquals(reviewer, nemo);

	}

	@Test
	public void testGetPendingReviews() {
		User nemo = new User("nemo", "123", "timmy", "nemo.timmy", "password2",
				"r257@hotmail.com", "1234", "15", "1254", "1325", "1").save();
		User nemo2 = new User("nemo2", "123", "timmy", "nemo.timmy2",
				"password2", "r257@hotmail.com", "1234", "15", "1254", "1325",
				"1").save();
		Task task = new Task().save();
		Project project = new Project("", 1, true, "").save();
		EventType et4 = new EventType("Default").save();
		Event event = new Event();
		event.type = et4;
		event.tasks.add(task);
		event.project = project;
		event.save();
		task.events.add(event);
		new TaskUserUser(nemo2, task).save();
		TaskUser expected = new TaskUser(nemo, task).save();
		List<TaskUser> pendingReviews = project
				.getPendingTaskReviewRequests();

		// TaskUser expected = new TaskUser(nemo, task).save();
		LinkedList<TaskUser> result = new LinkedList<TaskUser>();
		result.add(expected);
		// assertEquals(result.get(0), pendingReviews.get(0));
		assertEquals(1, result.size());
		assertEquals(result.get(0), expected);
	}

}
